feat(data-structures, linked-lists, remove cycle): utilities to detect and remove cycles#159
Conversation
…t and remove cycles
📝 WalkthroughWalkthroughCycle-detection and manipulation logic was moved from LinkedList methods into new standalone utilities in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@datastructures/linked_lists/linked_list_utils.py`:
- Around line 44-50: The cycle-detection block uses slow_pointer, fast_pointer
and an optional func but when a cycle is found and func is provided the function
calls func(...) then falls through to return False, contradicting the docstring;
update the code in that branch so after calling func(slow_pointer, fast_pointer)
the function returns True (i.e., ensure both the func and non-func paths return
True when slow_pointer is fast_pointer) so the function consistently reports a
detected cycle.
- Around line 71-77: The cycle-detection loop mixes identity and equality
comparisons: the initial check uses "is" (slow_pointer is fast_pointer) but the
loop uses "!=" which invokes Node.__eq__ (compares keys) and can mis-detect
cycles when distinct nodes have equal keys; update the loop condition to use
identity ("is not") so both comparisons use identity semantics (referencing
slow_pointer and fast_pointer in the function containing the loop) to correctly
count the cycle length.
- Line 132: Change the node comparison in the loop to use identity comparison:
in the while loop that currently checks "while current.next != fixed_pointer"
(variables current and fixed_pointer), replace the inequality operator with an
identity check so it reads as "while current.next is not fixed_pointer"; this
ensures consistent node identity comparison with other functions that use "is" /
"is not".
- Line 39: The tuple unpacking "fast_pointer, slow_pointer = head" is invalid
because head is a single Node; replace it by assigning both pointers to the head
node (set fast_pointer and slow_pointer to head) so both start at the list head;
update the initialization in linked_list_utils.py where fast_pointer,
slow_pointer and head are referenced to use individual assignments (e.g., set
fast_pointer = head and slow_pointer = head) so subsequent logic in functions
using fast_pointer and slow_pointer works correctly.
- Around line 99-105: Replace equality checks with identity checks in the
cycle-detection logic: where the code compares slow_pointer and fast_pointer
(currently using ==) and where it compares current and slow_pointer (currently
using !=), use "is" and "is not" respectively so comparisons use object identity
rather than Node.__eq__ (which compares keys); update the comparisons in the
function containing slow_pointer, fast_pointer, current and head to use "is" /
"is not" so distinct nodes with equal keys are not treated as the same node.
🧹 Nitpick comments (2)
datastructures/linked_lists/linked_list_utils.py (1)
27-27: Unnecessary f-string prefix on docstring.The docstring uses
f"""but contains no interpolated expressions. Use a regular docstring instead.♻️ Proposed fix
- f""" + """datastructures/linked_lists/__init__.py (1)
412-415: Guard clause is redundant with utility function behavior.The check on lines 412-413 is unnecessary because
remove_cyclein the utility already handles these cases viadetect_node_with_cyclereturningNoneand then returninghead. Consider removing for consistency with other delegating methods.♻️ Proposed simplification
def remove_cycle(self) -> Optional[Node]: """ Removes cycle if there exists. This will use the same concept as has_cycle method to check if there is a loop and remove the cycle Returns: Node: head node with cycle removed """ - if not self.head or not self.head.next: - return self.head - return remove_cycle(self.head)
… nth node from end
Describe your change:
Detect and remove cycles
Checklist:
Fixes: #{$ISSUE_NO}.Summary by CodeRabbit
New Features
Breaking Changes
✏️ Tip: You can customize this high-level summary in your review settings.